# -*- coding: utf-8 -*-
from django.db  import transaction 
from rest_framework.decorators  import action 
from rest_framework.viewsets  import ModelViewSet 
from core.response  import JsonResponse 
from core.filters  import DataLevelPermissionsFilter 
from core.mixins  import ExportSerializerMixin, ImportSerializerMixin, HistoryModelMixin 
from django_restql.mixins  import QueryArgumentsMixin
 
 
class CustomModelViewSet(
    ModelViewSet,
    ImportSerializerMixin,
    ExportSerializerMixin,
    QueryArgumentsMixin,
    HistoryModelMixin,
):
    """
    自定义增强版ModelViewSet，在DRF标准功能基础上扩展了以下特性：
    1. 统一标准化响应格式 
    2. 支持不同动作使用不同序列化器 
    3. 内置数据权限过滤 
    4. 支持导入导出功能 
    5. 支持历史记录追踪 
    6. 支持RESTQL查询语法 
    
    主要扩展功能：
    - ORM性能优化：支持values_queryset查询方式 
    - 多序列化器支持：通过xxx_serializer_class指定不同动作的序列化器 
    - 全字段过滤：filterset_fields = '__all__' 支持所有基础字段过滤 
    - 数据导入导出：通过import_resources/export_resources配置 
    """
 
    # 类属性定义 
    values_queryset = None  # 优化性能时使用的values queryset 
    search_fields = ()  # 搜索字段配置 
    ordering_fields = "__all__"  # 允许所有字段排序 
    filterset_class = None  # 过滤器类 
    filterset_fields = "__all__"  # 允许所有字段过滤 
    # 各动作对应的序列化器 
    list_serializer_class = None 
    create_serializer_class = None 
    update_serializer_class = None 
    retrieve_serializer_class = None 
    destroy_serializer_class = None 
    # 数据权限控制 
    permission_classes = []
    # 导入导出配置 
    import_resources = None 
    export_resources = None 
    # 额外的过滤器后端（默认包含数据权限过滤器）
    extra_filter_backends = [DataLevelPermissionsFilter]
 
    def filter_queryset(self, queryset):
        """
        增强版查询集过滤方法 
        合并默认filter_backends和extra_filter_backends进行过滤 
        """
        for backend in set(
            set(self.filter_backends)  | set(self.extra_filter_backends  or [])
        ):
            queryset = backend().filter_queryset(self.request,  queryset, self)
        return queryset 
 
    def get_queryset(self):
        """
        获取查询集，优先返回values_queryset（如果设置）
        用于优化查询性能，减少ORM对象实例化开销 
        """
        if getattr(self, "values_queryset", None):
            return self.values_queryset  
        return super().get_queryset()
 
    def get_serializer_class(self):
        """
        动态获取序列化器类 
        根据当前action自动选择对应的序列化器（格式：{action}_serializer_class）
        """
        action_serializer_name = f"{self.action}_serializer_class" 
        action_serializer_class = getattr(self, action_serializer_name, None)
        if action_serializer_class:
            return action_serializer_class 
        return super().get_serializer_class()
 
    def get_serializer(self, *args, **kwargs):
        """
        增强版序列化器获取方法 
        自动处理批量创建场景（当请求数据为列表时自动启用many=True）
        使用事务保证批量操作的原子性 
        """
        serializer_class = self.get_serializer_class() 
        kwargs.setdefault("context",  self.get_serializer_context()) 
        if isinstance(self.request.data,  list):
            with transaction.atomic(): 
                return serializer_class(many=True, *args, **kwargs)
        else:
            return serializer_class(*args, **kwargs)
 
    def create(self, request, *args, **kwargs):
        """
        创建资源 
        返回标准化响应格式，包含成功消息 
        """
        serializer = self.get_serializer(data=request.data,  request=request)
        serializer.is_valid(raise_exception=True) 
        self.perform_create(serializer) 
        return JsonResponse(data=serializer.data,  msg="新增成功")
 
    def list(self, request, *args, **kwargs):
        """
        获取资源列表 
        支持分页（可通过nopaginate参数禁用分页）
        返回标准化响应格式 
        """
        queryset = self.filter_queryset(self.get_queryset()) 
        page = self.paginate_queryset(queryset) 
        if page and not request.query_params.get("nopaginate"): 
            serializer = self.get_serializer(page,  many=True, request=request)
            return self.get_paginated_response(serializer.data) 
        serializer = self.get_serializer(queryset,  many=True, request=request)
        return JsonResponse(data=serializer.data,  msg="获取成功")
 
    def retrieve(self, request, *args, **kwargs):
        """
        获取单个资源详情 
        返回标准化响应格式 
        """
        instance = self.get_object() 
        serializer = self.get_serializer(instance) 
        return JsonResponse(data=serializer.data,  msg="获取成功")
 
    def update(self, request, *args, **kwargs):
        """
        更新资源（默认部分更新）
        处理预取缓存失效问题 
        返回标准化响应格式 
        """
        partial = kwargs.pop("partial",  True)
        instance = self.get_object() 
        serializer = self.get_serializer( 
            instance, data=request.data,  request=request, partial=partial 
        )
        serializer.is_valid(raise_exception=True) 
        self.perform_update(serializer) 
 
        # 处理预取缓存失效 
        if getattr(instance, "_prefetched_objects_cache", None):
            instance._prefetched_objects_cache = {}
        return JsonResponse(data=serializer.data,  msg="更新成功")
 
    def _delete_model(self, model):
        """
        内部删除方法 
        处理关联文件删除（如果模型有file字段）
        执行实际的销毁操作 
        """
        if hasattr(model, 'file'):
            model.file.delete()  
        self.perform_destroy(model)  
    
    def destroy(self, request, pk=None, *args, **kwargs):
        """
        删除单个资源 
        使用海象运算符(Python3.8+)简化代码 
        返回标准化响应格式 
        """
        if model := self.get_queryset().filter(id=pk).first(): 
            self._delete_model(model)
        return JsonResponse(msg="删除成功")
    
    @action(methods=['delete'], detail=False)
    def batch_delete(self, request, *args, **kwargs):
        """
        批量删除资源 
        根据请求数据中的ID列表批量删除 
        返回标准化响应格式 
        """
        for model in self.get_queryset().filter(id__in=request.data):  
            self._delete_model(model)
        return JsonResponse(msg="删除成功") 